بیایید کار را با یک مثال شروع کنیم. فرض کنیم شما در سایت شرکت خود یک دیتابیس دارید که حاوی جداول و کوئری های خاصی بوده تا با مشتریان شما تعامل داشته باشند. و شما حتی در سفر براحتی آنلاین شده و اقدام به مدیریت کاربران و مشتریان خود میکنید. شکل گیری دیتابیس شما در فرم ورود کاربران چیزی شبیه به این است:
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .$_GET['username']. " ' AND `password`= ' " .$_GET['password']. " ' ";
?>
هکری وارد سایت شما شده و به منظور آزمایش (آزمون خطا اغلب مطمئن ترین راه است!) کد زير در بخش نام کاربری وارد میکند:
' ; SHOW TABLES;
درحالت عادی ( اگر اقدامات امنیتی لحاظ نشده باشد) جداول پایگاه داده شما را مشاهده خواهد کرد! و از آنجا که او نام جداول را میداند ، این کد را وارد میکند:
'; DROP TABLE [your table's name];
your table’s nameنام تیبل مذکور است. حالا تمام اطلاعات از بین خواهند رفت..
*نکته: توجه کنید این مثال در بدبینانه ترین حالت ممکن روی میدهد و درحال حاضر وبسایتی را نمیابید که اینگونه و به این راحتی در دست شما قرار بگیرد! اینجا مثالی زده شد تا مفهوم اس کیو ال اینجکشن را ملموس تر دریابید. گاهاً یک هکر وقت زیادی را صرف آنالیز دیتابیس شما میکند.
مرحله اول: استفاده از mysql_real_escape_string()
این تابع PHP با گریز از فرار از کاراکترهای خاص استفاده شده در SQL Query از حمله جلوگیری میکند:
$q = "SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ";
?>
مرحله ۲:
استفاده از mysql_query()
با استفاده ازاین کد (یا تابعی شبیه به این) به هکر اجازه استفاده از رشته های خاص در فیلد “نام کاربری” را نمیدهید.
//connection
$database = mysql_connect("localhost", "username","password");
//db selection
mysql_select_db("database", $database);
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database);
?>
توصیه مهم:
کانکشن ها را متمرکز کنید.. تابع ‘include()’ فقط هنگام اتصال به دیتابیس اصلی استفاده شود. بگذارید خیالتان را راحت کنم! یک صفحه با نام ‘connections.php’ ایجاد کنید و کدهای زیر را در آن بریزید:
//connection
$database = mysql_connect("localhost", "username","password");
//db selection
mysql_select_db("database", $database);
?>
حالا باید تنظیمات جدیدی داشته باشیم تا موجب اثربخشی کدهای موجود در صفحه ای که دربالا تولید کرده ایم شویم:
include("connections.php");
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .mysql_real_escape_string( $_GET['username'] ). " ' AND `password`= ' " .mysql_real_escape_string( $_GET['password'] ). " ' ", $database);
?>
توصیه مهم:
هنگام شروع صفحه اطلاعات را اصطلاحاً پاکسازی (متمایز) نمایید.
بسیاری از زبان های برنامه نویسی شما را مجبور به تعیین متغیرها قبل از شروع کد نویسی میکنند که تنها می توانید آنها را در سراسر اسکریپت استفاده کنید. ولی در PHP مجبور انجام این کار نیستید و درهرجای دلخواه از برنامه میتوانید متغیر تعریف کنید ، با این حال آن را یک عادت خوب برای متمایز کردن متغیر های تان در آغاز هر حال صفحه بدانید!
خب شاید شاید شخصی این سوال برایش بوجود بیاید وقتی میتوان در هر جای صفحه متغیر تعریف نمود چرا باید اینطور عمل کنیم؟!! در پاسخ باید گفت تفصیل فلسفه این کار بسیار عمیق بوده که در حوصله این مقاله نیست ، ولی چند نمونه از دلایل فواید اینکار را فقط نام میبرم:
باگ ها اغلب نتیجه بی نظمی ها هستند؛
با تمایز متغیرها می توان آزادانه در سراسر خطوط برنامه نویسی از آنها استفاده کرد؛
این کار موجب جلوگیری از بسیاری از اشتباهات چه دستوری و چه الگوریتمی می گردد.
اگر در ابتدای صفحه متغیر تمیز داده شده باشد چیزی شبیه به این داریم:
include("connections.php");
$username = mysql_real_escape_string( $_GET['username'] );
$password = mysql_real_escape_string( $_GET['password'] );
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .$username. " ' AND `password`= ' " .$password. " ' ", $database);
?>
یا به این مثال دقت کنید:
function cleaner($input){
//clean variable, including mysql_real_escape_string()
}
include("connections.php");
$username = cleaner( $_GET['username'] );
$password = cleaner( $_GET['password'] );
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .$username. " ' AND `password`= ' " .$password. " ' ", $database);
?>
پیشنهاد:
پس از کدنویسی کدهای خود را چک کنید و از همه لحاظ آن ها را مورد ارزیابی تخصصی قرار دهید. حتماً مطمئن باشید پردازش های غیر ضروری روی سرور اعمال نشود. به این کد توجه کنید:
function cleaner($input){
//clean variable, including mysql_real_escape_string()
}
include("connections.php");
$username = cleaner( $_GET['username'] );
$password = cleaner( $_GET['password'] );
//Check if the input is blank.
if( ($password == '') || ($username == '')){
//dont let them pass
}
//Check if they are putting in way too many characters than should be allowed.
else if( (strlen($username) > ۲۰) || (strlen($password)> ۲۰) ){
//dont let them pass
}
//Passed all of our checks! Run query.
else {
$q = mysql_query("SELECT `id` FROM `users` WHERE `username`= ' " .$username. " ' AND `password`= ' " .$password. " ' ", $database);
}
?>
نظرات شما عزیزان:
موضوعات مرتبط: امنت سیستم ، ،
برچسبها: